

from PySide6.QtWidgets import QWidget, QVBoxLayout, QGroupBox, QFormLayout, QHBoxLayout, QPushButton, QLabel, QMessageBox
from PySide6.QtCore import Signal
from PySide6.QtGui import *
import win32serviceutil
from BatRunWoker import Worker
import os
import sys
import subprocess


class SvcWidget(QWidget):
    text_status = []
    lable_status = []
    btn_start = []
    btn_stop = []
    svc_dic = {}
    value_changed = Signal(str, object)

    def __init__(self, main_ui):
        super().__init__()
        self.main_ui = main_ui
        self.config = main_ui.config
        svcStr = self.config.get('service', 'servicelist')

        self.svc_name_list = svcStr.split(',')
        self.logger = main_ui.logger
        self.value_changed.connect(self.on_value_changed)
        self.ini_ui()
        self.ini_status()

    def ini_ui(self):
        # 添加服务tab
        vbox = QVBoxLayout(self)
        group_one_key = QGroupBox(self)
        group_one_key.setTitle("一键启动")
        one_vbox = QFormLayout(self)
        hbox_onekey = QHBoxLayout(self)

        btn_openbasedir = QPushButton(self)
        btn_openbasedir.setText("打开安装目录")
        btn_openbasedir.clicked.connect(self.show_install_directory)
        hbox_onekey.addWidget(btn_openbasedir)
        btn_reflesh = QPushButton(self)
        btn_reflesh.clicked.connect(self.ini_status)
        btn_reflesh.setText("刷新服务状态")
        hbox_onekey.addWidget(btn_reflesh)

        btn_one_key_start = QPushButton(self)
        btn_one_key_start.setText("一键启动所有服务")
        btn_one_key_start.clicked.connect(self.handle_one_key_start_bat)
        hbox_onekey.addWidget(btn_one_key_start)
        btn_one_key_stop = QPushButton(self)
        btn_one_key_stop.setText("一键停止所有服务")
        btn_one_key_stop.clicked.connect(self.handle_one_key_stop_bat)
        hbox_onekey.addWidget(btn_one_key_stop)

        one_vbox.addRow("一键启停", hbox_onekey)
        group_one_key.setLayout(one_vbox)

        group_one_key.setLayout(one_vbox)

        group_one_by_one = QGroupBox(self)
        group_one_by_one.setTitle("服务")
        vbox.addWidget(group_one_key)
        vbox.addWidget(group_one_by_one)

        layout = QFormLayout(self)
        group_one_by_one.setLayout(layout)
        for i in range(len(self.svc_name_list)):
            # print(self.svc_name_list[i])
            self.svc_dic[self.svc_name_list[i]] = -1
            status_value = self.svc_dic[self.svc_name_list[i]]
            if status_value is None:
                status_value = -1
            hbox = QHBoxLayout()

            qlabl = QLabel("未知", self)
            qlabl.setStyleSheet("color:black")
            self.lable_status.append(qlabl)

            btn_start = QPushButton("启动服务")
            self.btn_start.append(btn_start)
            btn_start.clicked.connect(self.handle_start_svc)

            btn_stop = QPushButton("停止服务")
            self.btn_stop.append(btn_stop)
            btn_stop.clicked.connect(self.handle_stop_svc)

            hbox.addWidget(qlabl)
            hbox.addWidget(btn_start)
            hbox.addWidget(btn_stop)

            layout.addRow(self.svc_name_list[i], hbox)

        self.setLayout(vbox)

    def set_value(self, key, value):
        self.svc_dic[key] = value
        self.value_changed.emit(key, value)

    def ini_status(self):
        self.logger.log_info(f"正在更新服务状态")
        for i in range(len(self.svc_name_list)):
            value = self.query_svc_status(self.svc_name_list[i])
            self.set_value(self.svc_name_list[i], value)
        print(self.svc_dic)
        self.logger.log_info(f"更新服务状态成功")

    def handle_start_svc(self):
        # print("开始按钮已禁用，防止重复点击。")
        btn = self.sender()
        index = self.btn_start.index(btn)
        svc_name = self.svc_name_list[index]

        print(f"正在开启{svc_name}服务")
        self.logger.log_info(f"正在开启{svc_name}服务")
        try:
            win32serviceutil.StartService(serviceName=svc_name)
            # 等待服务启动完成
            win32serviceutil.WaitForServiceStatus(
                serviceName=svc_name, status=4, waitSecs=5
            )
        except Exception as err:
            print(err)
            self.logger.log_error(f"{svc_name}:{err}")
            err_code = int(err.__getattribute__("winerror"))
            return err_code

        status = win32serviceutil.QueryServiceStatus(svc_name)
        print(f"--------{status[1]}-------")
        self.set_value(svc_name, status[1])
        print(f"{svc_name}服务状态：{status}")
        self.logger.log_info(f"{svc_name}服务状态：{status}")

        return status[1]

    def handle_stop_svc(self):
        btn = self.sender()
        index = self.btn_stop.index(btn)
        svc_name = self.svc_name_list[index]
        print(f"正在关闭{svc_name}服务")
        self.logger.log_info(f"正在关闭{svc_name}服务")
        try:
            win32serviceutil.StopService(serviceName=svc_name)
            # 等待服务关闭完成
            win32serviceutil.WaitForServiceStatus(
                serviceName=svc_name, status=1, waitSecs=5
            )
        except Exception as err:
            print(err)
            self.logger.log_error(f"{svc_name}:{err}")
            err_code = int(err.__getattribute__("winerror"))
            return err_code
        status = win32serviceutil.QueryServiceStatus(svc_name)
        self.set_value(svc_name, status[1])
        print(f"{svc_name}服务状态：{status}")
        self.logger.log_info(f"{svc_name}服务状态：{status}")
        return status[1]

    def show_install_directory(self):
        """
        打开安装目录
        """
        try:
            base_dir = self.main_ui.base_dir
            folder_path = os.path.dirname(base_dir)
            absolute_path = os.path.abspath(folder_path)
            self.logger.log_info(f"打开路径{absolute_path}")
            os.startfile(absolute_path)

        except Exception as err:
            self.logger.log_error(err)

    def handle_one_key_start_bat(self):
        """
        一键启动所有服务的bat脚本
        """
        # path = self.config.get('service', 'onekeystart')
        self.logger.log_info(f"开始一键启动服务")
        one_key_path = self.config.get('service', 'onekeystart')
        absolute_path = os.path.abspath(one_key_path)
        self.logger.log_info(f"脚本路径{absolute_path}")
        self.worker = Worker(
            bat_file=absolute_path,
            logger=self.logger,
        )
        self.worker.finished.connect(lambda: self.ini_status())
        self.worker.start()

    def handle_one_key_stop_bat(self):
        """
        一键停止所有服务的bat脚本
        """
        reply = QMessageBox.warning(
            self,
            "确认",
            "确定要停止所有服务吗?",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No,
        )
        # path = self.config.get('service', 'onekeystop')
        if reply == QMessageBox.Yes:
            self.logger.log_info(f"开始一键停止服务")
            one_key_path = self.config.get('service', 'onekeystop')
            absolute_path = os.path.abspath(one_key_path)
            self.logger.log_info(f"脚本路径{absolute_path}")
            self.worker = Worker(
                bat_file=absolute_path,
                logger=self.logger,
            )
            self.worker.finished.connect(lambda: self.ini_status())
            self.worker.start()
        else:
            self.logger.log_info(f"取消操作")

    def query_svc_status(self, svc_name):
        # 查询服务的状态
        # SERVICE_STOPPED (1): 服务已停止
        # SERVICE_START_PENDING (2): 服务正在启动
        # SERVICE_STOP_PENDING (3): 服务正在停止
        # SERVICE_RUNNING (4): 服务正在运行
        # SERVICE_CONTINUE_PENDING (5): 服务正在继续
        # SERVICE_PAUSE_PENDING (6): 服务正在暂停
        # SERVICE_PAUSED (7): 服务已暂停

        # 自定义 -1 错误状态
        # 1060 服务未安装
        try:
            status_obj = win32serviceutil.QueryServiceStatus(svc_name)
            print(status_obj)
            print(f"查询到{svc_name}的服务状态为：{status_obj}")
            self.logger.log_info(f"查询到{svc_name}的服务状态为：{status_obj}")
        except Exception as err:
            self.logger.log_error(f"{svc_name}:{err}")
            err_code = int(err.__getattribute__("winerror"))
            return err_code

        if status_obj is not None:
            return status_obj[1]
        else:
            return -1

    def on_value_changed(self, key, value):
        # print(f"Value for key '{key}' changed to '{value}'")
        index = self.svc_name_list.index(key)
        svc_name = key

        i = 10
        if value == "":
            pass
        else:
            i = int(value)
        # SERVICE_STOPPED (1): 服务已停止
        # SERVICE_START_PENDING (2): 服务正在启动
        # SERVICE_STOP_PENDING (3): 服务正在停止
        # SERVICE_RUNNING (4): 服务正在运行
        # SERVICE_CONTINUE_PENDING (5): 服务正在继续
        # SERVICE_PAUSE_PENDING (6): 服务正在暂停
        # SERVICE_PAUSED (7): 服务已暂停

        # 自定义 -1 错误状态
        if i == -1:
            self.lable_status[index].setText("错误")
            self.lable_status[index].setStyleSheet("color:red")
            self.btn_stop[index].setEnabled(False)
            self.btn_start[index].setEnabled(False)
        elif i == 1:
            self.lable_status[index].setText("服务已停止")
            self.lable_status[index].setStyleSheet("color:red")
            self.btn_stop[index].setEnabled(False)
            self.btn_start[index].setEnabled(True)
        elif i == 2:
            self.lable_status[index].setText("服务正在启动中...")
            self.lable_status[index].setStyleSheet("color:black")
            self.btn_stop[index].setEnabled(False)
            self.btn_start[index].setEnabled(False)
        elif i == 3:
            self.lable_status[index].setText("服务正在停止中...")
            self.lable_status[index].setStyleSheet("color:black")
            self.btn_stop[index].setEnabled(False)
            self.btn_start[index].setEnabled(False)
        elif i == 4:
            self.lable_status[index].setText("服务正在运行")
            self.lable_status[index].setStyleSheet("color:green")
            self.btn_stop[index].setEnabled(True)
            self.btn_start[index].setEnabled(False)
        elif i == 5:
            self.lable_status[index].setText("服务正在继续...")
            self.lable_status[index].setStyleSheet("color:black")
            self.btn_stop[index].setEnabled(False)
            self.btn_start[index].setEnabled(False)
        elif i == 6:
            self.lable_status[index].setText("服务正在暂停...")
            self.lable_status[index].setStyleSheet("color:black")
            self.btn_stop[index].setEnabled(False)
            self.btn_start[index].setEnabled(False)
        elif i == 7:
            self.lable_status[index].setText("服务已暂停")
            self.lable_status[index].setStyleSheet("color:black")
            self.btn_stop[index].setEnabled(True)
            self.btn_start[index].setEnabled(True)
        elif i == 1060:
            self.lable_status[index].setText("服务未安装")
            self.lable_status[index].setStyleSheet("color:grey")
            self.btn_stop[index].setEnabled(False)
            self.btn_start[index].setEnabled(False)
        else:
            self.lable_status[index].setText("未知")
            self.lable_status[index].setStyleSheet("color:red")
            self.btn_stop[index].setEnabled(False)
            self.btn_start[index].setEnabled(False)

# if __name__ == "__main__":
#     app = QApplication(sys.argv)
#     widget = RedisWidget(main_ui=myMainWindow())
#     widget.resize(800, 600)
#     widget.show()
#     sys.exit(app.exec())
